package com.mai4j.maiadmin.support.web.binding;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 席有芳 on 2021/11/30.
 *
 * @author 席有芳
 */
public class ReqParamHelper {

    /**
     * 位置
     */
    public static class Position {

        enum Type {
            TEXT,       // 不同Text
            GROUP       // 分组[]
        }

        int start;
        int end;
        Type type;

        public Position(int start, int end, Type type) {
            this.start = start;
            this.end = end;
            this.type = type;
        }
    }

    /**
     * request 参数转成Map
     *
     * @param request request
     * @return Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> getParams(HttpServletRequest request) {
        Map<String, Object> paras = new LinkedHashMap<>();
        Map<String, String[]> parameters = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
            List<String> paths = parsingPathV2(entry.getKey());
            String[] value = entry.getValue();
            Map<String, Object> current = paras;
            for (int i = 0; i < paths.size(); i++) {
                String path = paths.get(i);
                if (i == paths.size() - 1) { // 最后的路径
                    current.put(path, value.length == 1 ? value[0] : value);
                } else {
                    Map<String, Object> child = (Map<String, Object>) current.get(path);
                    if (child == null) {
                        child = new LinkedHashMap<>();
                        current.put(path, child);
                    }
                    current = child;
                }
            }
        }
        return paras;
    }

    /**
     * 解析路径的版本2
     *
     * @param key key
     * @return Map的路径
     */
    private static List<String> parsingPathV2(String key) {
        List<String> paths = new ArrayList<>(); // 路径
        List<Position> positions = parsingPathPosition(key);
        for (Position position : positions) {
            switch (position.type) {
                case GROUP:
                    String group = key.substring(position.start + 1, position.end - 1).trim();
                    paths.add("".equals(group) ? "0" : group);
                    break;
                case TEXT:
                    String text = trim(key.substring(position.start, position.end).trim(), '.'); // 出去开头的.
                    String[] subPaths = text.split("[.]");
                    for (String subPath : subPaths) {
                        paths.add("".equals(subPath) ? "0" : subPath);
                    }
                    break;
            }
        }
        return paths;
    }

    /**
     * 根据字符 trim
     *
     * @param s s
     * @param c char
     * @return trim value
     */
    private static String trim(String s, char c) {
        char[] value = s.toCharArray();
        int len = value.length;
        int st = 0;
        while ((st < len) && (value[st] == c)) {
            st++;
        }
        while ((st < len) && (value[len - 1] == c)) {
            len--;
        }
        return ((st > 0) || (len < value.length)) ? s.substring(st, len) : s;
    }

    /**
     * 解析路径位置
     *
     * @param key key
     * @return Positions
     */
    private static List<Position> parsingPathPosition(String key) {
        List<Position> positions = new ArrayList<>();
        List<Position> matchPositions = new ArrayList<>();
        Pattern pattern = Pattern.compile("\\[([^]]*)]");
        Matcher matcher = pattern.matcher(key);
        while (matcher.find()) {
            matchPositions.add(new Position(matcher.start(), matcher.end(), Position.Type.GROUP));
        }
        if (matchPositions.isEmpty()) {
            positions.add(new Position(0, key.length(), Position.Type.TEXT));
        } else {
            for (int j = 0; j < matchPositions.size(); j++) {
                Position currentPosition = matchPositions.get(j);                                           // 当前位置
                Position nextPosition = j + 1 < matchPositions.size() ? matchPositions.get(j + 1) : null;  // 下一个位置
                if (j == 0 && currentPosition.start > 0) {
                    positions.add(new Position(0, currentPosition.start, Position.Type.TEXT));
                }
                positions.add(new Position(currentPosition.start, currentPosition.end, Position.Type.GROUP));
                if (nextPosition != null) {
                    if (currentPosition.end != nextPosition.start) {
                        positions.add(new Position(currentPosition.end, nextPosition.start, Position.Type.TEXT));
                    }
                }
                if (nextPosition == null && currentPosition.end < key.length()) {
                    positions.add(new Position(currentPosition.end, key.length(), Position.Type.TEXT));
                }
            }
        }
        return positions;
    }
}
